package com.zzyl.nursing.service.impl;

import java.rmi.registry.LocateRegistry;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.List;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInConfigDto;
import com.zzyl.nursing.service.*;
import com.zzyl.nursing.util.CodeGenerator;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.CheckInMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;

/**
 * 入住Service业务层处理
 * 
 * @author zsn
 * @date 2025-05-17
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService
{
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private IBedService bedService;
    @Autowired
    private IElderService elderService;
    @Autowired
    private IContractService contractService;
    @Autowired
    private ICheckInConfigService checkInConfigService;

    /**
     * 查询入住详情
     *
     * @param id
     * @return
     */
    @Override
    public CheckInDetailVo detail(Long id) throws Exception {
        //1.根据id查询入住信息
        CheckIn checkIn = this.getById(id);

        //2.判断入住信息是否为空
        if (checkIn==null){
            throw new Exception("没有对应id的入住信息");
        }
        //3.根据入住信息获取老人信息
        //创建老人值对象实例
        CheckInElderVo checkInElderVo = new CheckInElderVo();
        Elder elder = elderService.lambdaQuery().eq(Elder::getIdCardNo, checkIn.getIdCardNo())
                .one();

        BeanUtils.copyProperties(elder,checkInElderVo);
        //设置年龄age
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate parse = LocalDate.parse(elder.getBirthday(), formatter);
        checkInElderVo.setAge(Period.between(parse, LocalDate.now()).getYears());

        //4.查询合同
        //创建Contract实例类实例
        Contract contract = new Contract();
        //获取数据库中的合同信息
        Contract contractInfo = contractService.getOne(Wrappers.<Contract>lambdaQuery().eq(Contract::getElderId, elder.getId()));
        BeanUtils.copyProperties(contractInfo,contract);

        //5.查询入住配置
        //创建入住配置值对象实例
        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
        CheckInConfig checkInConfig = checkInConfigService.getOne(Wrappers.<CheckInConfig>lambdaQuery().eq(CheckInConfig::getCheckInId, checkIn.getId()));
        BeanUtils.copyProperties(checkInConfig,checkInConfigVo);
        checkInConfigVo.setStartDate(checkIn.getStartDate());
        checkInConfigVo.setEndDate(checkIn.getEndDate());
        checkInConfigVo.setBedNumber(checkIn.getBedNumber());

        //6.转换家属列表
        // 将字符串转回 List<ElderFamilyVo>
        List<ElderFamilyVo> familyList = JSONUtil.toList(checkIn.getRemark(), ElderFamilyVo.class);



        //7.整合数据并返回
        CheckInDetailVo checkInDetailVo = new CheckInDetailVo(checkInElderVo,familyList,checkInConfigVo,contract);

        return checkInDetailVo;
    }

    /**
     * 查询入住
     * 
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询入住列表
     * 
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn)
    {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn)
    {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn)
    {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住
     * 
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息
     * 
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 申请入住
     *
     * @param checkInApplyDto
     */
    @Override
    public void apply(CheckInApplyDto checkInApplyDto) {

        //1.校验老人是否已入住
        String idCardNo = checkInApplyDto.getCheckInElderDto().getIdCardNo();//获取老人身份证号
        Long countCheckIn = this.lambdaQuery().eq(CheckIn::getIdCardNo, idCardNo)
                .eq(CheckIn::getStatus, 0).count();
        if(countCheckIn==1){
            throw new RuntimeException("老人已入住");
        }

        //2.先判断床位是否存在并且未入住,存在再更新床位状态
        Long bedId = checkInApplyDto.getCheckInConfigDto().getBedId();
        Bed bed = bedService.lambdaQuery().eq(Bed::getId, bedId)
                .eq(Bed::getBedStatus, 0).one();
        if(bed==null){
            throw new RuntimeException("不存在对应的床位");
        }

        boolean resultBedUpdate = bedService.lambdaUpdate().eq(Bed::getId, bedId)
                .set(Bed::getBedStatus, 0)
                .update();
        if (!resultBedUpdate){
            throw new RuntimeException("更新床位状态失败");
        }


        //3.新增或更新老人
        //查询老人信息
        Elder elder = elderService.lambdaQuery().eq(Elder::getIdCardNo, idCardNo)
                .one();


        //判断老人信息是否为空,为空则新增,不为空则更新
        Elder elderInfo = new Elder();
        /*if (elder==null){
            elder = new Elder();
        }
        //拷贝
        BeanUtils.copyProperties(checkInApplyDto.getCheckInElderDto(),elder);
        elder.setStatus(4);
        elder.setBedId(bedId);
        elder.setBedNumber(bed.getBedNumber());
        boolean resultElder = elderService.save(elder);
        if(!resultElder){
            throw new RuntimeException("新增老人信息失败");
        }*/

        if(elder==null){
            //新增老人信息到老人表中
            //拷贝
            BeanUtils.copyProperties(checkInApplyDto.getCheckInElderDto(),elderInfo);
            elderInfo.setStatus(4);
            elderInfo.setBedId(bedId);
            elderInfo.setBedNumber(bed.getBedNumber());
            boolean resultElder = elderService.save(elderInfo);
            if(!resultElder){
                throw new RuntimeException("新增老人信息失败");
            }
        }else{
            //更新老人信息到老人表中
            BeanUtils.copyProperties(checkInApplyDto.getCheckInElderDto(),elderInfo);
            elderInfo.setStatus(4);
            elderInfo.setBedId(bedId);
            elderInfo.setBedNumber(bed.getBedNumber());
            boolean resultElder = elderService.updateById(elderInfo);
            if (!resultElder){
                throw new RuntimeException("更新老人信息失败");
            }
        }
        //4.新增签约办理
        //创建新Contract对象
        Contract contract = new Contract();
        // 拷贝
        BeanUtils.copyProperties(checkInApplyDto.getCheckInContractDto(),contract);
        //设置部分字段值
        contract.setElderId(elderInfo.getId());
        contract.setContractNumber("HT" + CodeGenerator.generateContractNumber());
        contract.setElderName(elderInfo.getName());
        contract.setStartDate(checkInApplyDto.getCheckInConfigDto().getStartDate());
        contract.setEndDate(checkInApplyDto.getCheckInConfigDto().getEndDate());
        contract.setStatus(LocalDateTime.now().isBefore(contract.getStartDate()) ? 0 : LocalDateTime.now().isAfter(contract.getEndDate()) ? 3 : LocalDateTime.now().isAfter(contract.getSignDate()) ? 2 : 1 );
        boolean resultContract = contractService.save(contract);

        if (!resultContract){
            throw new RuntimeException("新增签约办理失败");
        }

        //5.新增入住信息
        //创建入住信息实例
        CheckIn checkIn = new CheckIn();
        //拷贝
        BeanUtils.copyProperties(checkInApplyDto.getCheckInConfigDto(),checkIn);
        checkIn.setElderName(elderInfo.getName());
        checkIn.setElderId(elderInfo.getId());
        checkIn.setIdCardNo(idCardNo);
        checkIn.setBedNumber(bed.getBedNumber());
        checkIn.setStatus(0);
        checkIn.setRemark(JSONUtil.toJsonStr(checkInApplyDto.getElderFamilyDtoList()));
        boolean resultCheckIn = this.save(checkIn);
        if (!resultCheckIn){
            throw new RuntimeException("新增入住信息失败");
        }

        //6.新增入住配置
        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(checkInApplyDto.getCheckInConfigDto(),checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
        boolean resultCheckInConfig = checkInConfigService.save(checkInConfig);
        if (!resultCheckInConfig){
            throw new RuntimeException("新增入住配置失败");
        }
    }
}
